package org.deltaset.samples.mvc.menu;

import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.ManagedBean;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.metamodel.EntityType;
import org.deltaset.desktop.AppItem;
import org.deltaset.desktop.MenuGroup;
import org.deltaset.desktop.MenuItem;

/**
 *
 * @author dmakariev
 */
@ManagedBean
public class MenuRegistry {

    private final List<AppItem> topMenu;

    public MenuRegistry() {
        topMenu = appMenu();
    }

    //this should be used by the session provider.
    public List<AppItem> loadTopMenu() {
        if (topMenu.get(0).getMenuGroups().size() < 2) {
            topMenu.get(0).getMenuGroups().add(autoObjects());
            return topMenu;
        }
        return topMenu;
    }

    //TODO: change to richer registry API for menu items.
    public List<AppItem> getTopMenu() {
        return topMenu;
    }
    private EntityManager entityManager;

    @PersistenceContext
    void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    public static MenuGroup autoObjects(final String groupName, final String packageName) {
        final MenuGroup group = new MenuGroup(groupName);
        final List<Class> entityClasses = MenuRegistry.getEntityClasses(packageName);
        for (Class entityClass : entityClasses) {
            if (!Modifier.isAbstract(entityClass.getModifiers())) {
                group.addRefreshable(entityClass.getSimpleName(), "/record/meta-entity.xhtml", "entityClassName:" + entityClass.getName());
            }
        }
        return group;
    }

    private static List<Class> getEntityClasses(final String packageName) {

        final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        final boolean recursive = false;
        final List<Class> entityClasses = ClasspathScanner.getEntityClasses(classLoader, packageName, recursive);
        return entityClasses;


    }

    private MenuGroup autoObjects() {
        final MenuGroup group = new MenuGroup("Auto Objects");
        for (EntityType<?> entityType : entityManager.getMetamodel().getEntities()) {
            final Class entityClass = entityType.getJavaType();
            if (!Modifier.isAbstract(entityClass.getModifiers())) {
                group.addRefreshable(entityClass.getSimpleName(), "/record/meta-entity.xhtml", "entityClassName:" + entityClass.getName());
            }
        }
        return group;
    }

    private static List<AppItem> appMenu() {

        final MenuItem defaultMenuItem = new MenuItem("simple", "/simple.xhtml");
        final MenuGroup simple = new MenuGroup("Simple");
        simple.add(defaultMenuItem);

        final List<MenuGroup> groups = new ArrayList<MenuGroup>();
        groups.add(simple);

        final AppItem appHome = new AppItem("appId-home", "Home", "/home.xhtml", defaultMenuItem, groups);

        final List<AppItem> discoveredMenuItems = new ArrayList<AppItem>();
        discoveredMenuItems.add(appHome);
        return discoveredMenuItems;

    }
}
